package com.powernode.ssm.utils;

import com.powernode.ssm.config.AppProperties;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64;

public class TokenUtils {

    // ======================
    // 🔐 请将此处替换为你自己生成的 16字节密钥的 Base64（推荐 128位 AES）
    // 你可以运行 GenerateAesKey.java 获取一个
    // 示例（请替换成你自己的！！！）：
    private static final String FIXED_AES_KEY_BASE64 = AppProperties.getAppEncryptKey(); // ← 替换为你的真实密钥
    // ======================

    // AES 密钥字节长度必须为 16 (128bit), 24 (192), 或 32 (256)
    private static final int AES_KEY_SIZE = 16; // 128 bit

    /**
     * 加密方法：相同明文，每次加密结果不同（因为随机IV）
     */
    public static String encrypt(String plaintext) {
        try {
            byte[] keyBytes = Base64.getDecoder().decode(FIXED_AES_KEY_BASE64);

            if (keyBytes.length != AES_KEY_SIZE) {
                throw new IllegalArgumentException("AES 密钥必须是 16 字节（128位）");
            }

            // 1. 随机生成 16 字节 IV
            byte[] iv = new byte[16];
            new SecureRandom().nextBytes(iv);
            IvParameterSpec ivSpec = new IvParameterSpec(iv);

            // 2. 构造 AES Key
            SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "AES");

            // 3. 初始化 Cipher (AES/CBC/PKCS5Padding)
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);

            // 4. 加密内容
            byte[] encrypted = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));

            // 5. 拼接 IV + 密文 （IV 前，密文后，总共 16 + encrypted.length）
            byte[] combined = new byte[iv.length + encrypted.length];
            System.arraycopy(iv, 0, combined, 0, iv.length);
            System.arraycopy(encrypted, 0, combined, iv.length, encrypted.length);

            // 6. 返回 Base64
            return Base64.getEncoder().encodeToString(combined);

        } catch (Exception e) {
            throw new RuntimeException("AES 加密失败", e);
        }
    }

    /**
     * 解密方法
     */
    public static String decrypt(String token) {
        try {
            byte[] combined = Base64.getDecoder().decode(token);

            if (combined.length < 16) {
                throw new IllegalArgumentException("密文太短，无法提取 IV");
            }

            // 1. 提取前 16 字节作为 IV
            byte[] iv = new byte[16];
            System.arraycopy(combined, 0, iv, 0, 16);
            IvParameterSpec ivSpec = new IvParameterSpec(iv);

            // 2. 剩余的是密文
            byte[] encrypted = new byte[combined.length - 16];
            System.arraycopy(combined, 16, encrypted, 0, encrypted.length);

            // 3. 获取密钥
            byte[] keyBytes = Base64.getDecoder().decode(FIXED_AES_KEY_BASE64);
            if (keyBytes.length != AES_KEY_SIZE) {
                throw new IllegalArgumentException("AES 密钥必须是 16 字节");
            }
            SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "AES");

            // 4. 解密
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);

            byte[] decrypted = cipher.doFinal(encrypted);

            return new String(decrypted, StandardCharsets.UTF_8);

        } catch (Exception e) {
            throw new RuntimeException("AES 解密失败", e);
        }
    }

    /**
     * 生成一个新的随机 16 字节 AES 密钥，并返回 Base64 编码（可用于测试或动态密钥）
     */
    public static String generateRandomAesKeyBase64() {
        byte[] key = new byte[AES_KEY_SIZE]; // 16字节
        new SecureRandom().nextBytes(key);
        return Base64.getEncoder().encodeToString(key);
    }

    // ======================
    // 可选：测试 main 方法
    // ======================
    public static void main(String[] args) {
        // 示例：生成一个新密钥（可选，仅测试用）
        String randomKey = generateRandomAesKeyBase64();
        System.out.println("🔑 随机生成的 16字节 AES 密钥（Base64）：");
        System.out.println(randomKey);

        // 建议将上面的 randomKey 复制，然后设置到 FIXED_AES_KEY_BASE64 中使用

        // 示例用法（请确保 FIXED_AES_KEY_BASE64 已设置为真实密钥）
        String userid = "1001";

        String token1 = encrypt(userid);
        String token2 = encrypt(userid);

        System.out.println("🔐 加密后 Token1: " + token1);
        System.out.println("🔐 加密后 Token2: " + token2); // 和 token1 不同

        System.out.println("🔓 解密 Token1: " + decrypt(token1)); // user123
        System.out.println("🔓 解密 Token2: " + decrypt(token2)); // user123
    }
}